package com.shop.shopserver.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shop.shopcommon.constant.MessageConstant;
import com.shop.shopcommon.context.SecurityContext;
import com.shop.shopcommon.enumeration.*;
import com.shop.shopcommon.exception.Base.OrderException;
import com.shop.shopcommon.result.Result;
//import com.shop.shopcommon.utils.DelayMessageSender;
import com.shop.shopcommon.utils.SnowflakeIdGenerator;
import com.shop.shoppojo.dto.CartDeleteDTO;
import com.shop.shoppojo.dto.StockTotalDTO;
import com.shop.shoppojo.dto.SubmitOrderDTO;
import com.shop.shoppojo.entity.Cart;
import com.shop.shoppojo.entity.Goods;
import com.shop.shoppojo.entity.User;
import com.shop.shoppojo.entity.UserOrder;
import com.shop.shoppojo.vo.SubmitOrderVO;
import com.shop.shopserver.annotation.InsertCreateTime;
import com.shop.shopserver.controller.user.CartController;
import com.shop.shopserver.mapper.*;
import com.shop.shopserver.sender.OrderDelayMessageSender;
import com.shop.shopserver.service.OrderService;
import com.shop.shopserver.service.SubmitOrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.web.bind.annotation.RequestBody;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;


@Service
@Slf4j
public class SubmitOrderServiceImpl extends ServiceImpl<OrderMapper, UserOrder> implements SubmitOrderService {

    @Autowired
    private OrderService orderService;

    @Autowired
    private OrderDelayMessageSender orderDelayMessageSender;

    @Autowired
    private CartMapper cartMapper;

    @Autowired
    private CartController cartController;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private GoodsMapper goodsMapper;

    @Autowired
    private StockTotalServiceImpl stockTotalServiceImpl;

    @Autowired
    private TransactionTemplate transactionTemplate;

    @Autowired
    private OrderDelayMessageSender delayMessageSender;

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private StockTotalMapper stockTotalMapper;

    private final SnowflakeIdGenerator idGenerator = new SnowflakeIdGenerator(1L, 1L); // 初始化雪花算法生成器


    /**
     * 直接结算-提交订单
     * @param submitOrderDTO
     * @return
     * @throws Exception
     */


    @InsertCreateTime(OperationType.INSERT)
    @Transactional(rollbackFor = Exception.class)
    public Result<List<SubmitOrderVO>> submitOrderGoodsId(SubmitOrderDTO submitOrderDTO) throws Exception {
        Goods goods = goodsMapper.selectOne(new LambdaQueryWrapper<Goods>().eq(Goods::getId, submitOrderDTO.getGoodsId()));
        //更新商品库存以及销售量
        StockTotalDTO stockTotalDTO = new StockTotalDTO();
        BeanUtils.copyProperties(submitOrderDTO, stockTotalDTO);
        stockTotalServiceImpl.updateStockTotal(stockTotalDTO);
        //设置默认信息
        UserOrder userOrder = UserOrder
                .builder()
                .id(idGenerator.nextId())
                .orderPrice((BigDecimal.valueOf(submitOrderDTO.getGoodsNum()*Double.parseDouble(goods.getGoodsPriceMin().toString()))).setScale(2))
                .orderNo(UUID.randomUUID().toString())
                .mode(PayModeType.DIRECT_PAY)
                .payStatus(PayStatusType.NOT_PAY)
                .deliveryType(DeliveryType.DELIVERY)
                .orderStatus(OrderStatusType.UNPAID)
                .userId(getUserIdByUsername().getId())
                .build();
        BeanUtils.copyProperties(submitOrderDTO, userOrder);

        log.info("提交订单处userId:"+ getUserIdByUsername().getId());
        //保存
        orderService.save(userOrder);

        System.out.println("新增订单为"+userOrder);

        //监听订单支付，超过时间不支付，取消订单
        delayMessageSender.run(String.valueOf(userOrder.getId()));

        SubmitOrderVO submitOrderVO = new SubmitOrderVO();
        BeanUtils.copyProperties(userOrder, submitOrderVO);
        submitOrderVO.setId(userOrder.getId().toString());
        List<SubmitOrderVO> submitOrderVOList =new ArrayList<>();
        submitOrderVOList.add(submitOrderVO);
        return Result.success(submitOrderVOList, "返回成功");
    }


    /**
     * 购物车结算-提交订单
     * @param submitOrderDTO
     * @return
     * @throws Exception
     */
//    @InsertCreateTime(OperationType.INSERT)
//    @Transactional(rollbackFor = Exception.class)
//    public Result<List<SubmitOrderVO>> submitOrderCart(SubmitOrderDTO submitOrderDTO) throws Exception {
//        String[] cartIdsArray = submitOrderDTO.getCartIds().split(",");
//        List<SubmitOrderVO> submitOrderVOList = null;
//        for (String s : cartIdsArray) {
//            //查找id对应的购物车信息
//            Cart cart = cartMapper.selectOne(new LambdaQueryWrapper<Cart>().eq(Cart::getId, s));
//            if (cart == null){
//                throw new OrderException(MessageConstant.SHOPPING_CART_IS_NULL);
//            }
//            Goods goods = goodsMapper.selectOne(new LambdaQueryWrapper<Goods>().eq(Goods::getId, submitOrderDTO.getGoodsId()));
//            //更新商品库存以及销售量
//            StockTotalDTO stockTotalDTO = new StockTotalDTO();
//            BeanUtils.copyProperties(submitOrderDTO, stockTotalDTO);
//            stockTotalServiceImpl.updateStockTotal(stockTotalDTO);
//            //设置到order
//            UserOrder userOrder = UserOrder
//                    .builder()
//                    .id(idGenerator.nextId())
//                    .orderPrice(BigDecimal.valueOf(submitOrderDTO.getGoodsNum()*Double.parseDouble(goods.getGoodsPriceMin().toString())).setScale(2))
//                    .orderNo(UUID.randomUUID().toString())
//                    .mode(PayModeType.SHOPPING_CART_PAY)
//                    .payStatus(PayStatusType.NOT_PAY)
//                    .deliveryType(DeliveryType.DELIVERY)
//                    .orderStatus(OrderStatusType.UNPAID)
//                    .userId(getUserIdByUsername().getId())
//                    .build();
//
//            BeanUtils.copyProperties(submitOrderDTO, userOrder);
//            //设置其他物流状态，计算订单金额等
//
//            //保存到数据库
//            orderService.save(userOrder);
//            System.out.println("购物车结算新增订单为"+userOrder);
//            //保存order
//            SubmitOrderVO submitOrderVO = new SubmitOrderVO();
//            BeanUtils.copyProperties(userOrder, submitOrderVO);
//            submitOrderVO.setId(userOrder.getId().toString());
//            submitOrderVOList = new ArrayList<>();
//            submitOrderVOList.add(submitOrderVO);
//
//            //监听订单支付，超过时间不支付，取消订单
//            orderDelayMessageSender.run(String.valueOf(userOrder.getId()));
//            //删除购物车对应商品信息
//            List<String> stringList = new ArrayList<>(Arrays.asList(cartIdsArray));
//            CartDeleteDTO cartDeleteDTO = CartDeleteDTO
//                    .builder()
//                    .goodsId(cart.getGoodsId())
//                    .cartIds(stringList)
//                    .build();
//
//            cartController.deleteCart(cartDeleteDTO);
//
//        }
//        return Result.success(submitOrderVOList, "返回成功");
//    }

    @InsertCreateTime(OperationType.INSERT)
    @Transactional(rollbackFor = Exception.class)
    public Result<List<SubmitOrderVO>> submitOrderCart(SubmitOrderDTO submitOrderDTO) throws Exception {
        String[] cartIdsArray = submitOrderDTO.getCartIds().split(",");
        for (String s : cartIdsArray) {
            //查找id对应的购物车信息
            Cart cart = cartMapper.selectOne(new LambdaQueryWrapper<Cart>()
                    .eq(Cart::getId, Long.valueOf(s))
                    .eq(Cart::getUserId, getUserIdByUsername().getId())
            );
            if (cart == null){
                throw new OrderException(MessageConstant.SHOPPING_CART_IS_NULL);
            }
            // 根据goods_id查找商品信息
            Goods goods = goodsMapper.selectOne(new LambdaQueryWrapper<Goods>().eq(Goods::getId, cart.getGoodsId()));
            if (goods == null){
                throw new OrderException("商品不存在");
            }
            //设置到order
            UserOrder userOrder = UserOrder
                    .builder()
                    .id(idGenerator.nextId())
                    .orderPrice(BigDecimal.valueOf(cart.getGoodsNum()*Double.parseDouble(goods.getGoodsPriceMin().toString())).setScale(2))
                    .orderNo(UUID.randomUUID().toString())
                    .mode(PayModeType.SHOPPING_CART_PAY)
                    .payStatus(PayStatusType.NOT_PAY)
                    .goodsNum(cart.getGoodsNum())
                    .goodsId(cart.getGoodsId())
                    .createTime(LocalDateTime.now())
                    .deliveryType(DeliveryType.DELIVERY)
                    .orderStatus(OrderStatusType.UNPAID)
                    .userId(getUserIdByUsername().getId())
                    .build();
            //更新商品库存以及销售量

            //设置其他物流状态，计算订单金额等
            stockTotalMapper.updataStockAndSales(cart.getGoodsId(), cart.getGoodsNum());
            //保存订单到数据库
            orderMapper.insert(userOrder);

            //监听订单支付，超过时间不支付，取消订单
            orderDelayMessageSender.run(String.valueOf(userOrder.getId()));
            //删除购物车对应商品信息
            cartMapper.delete(new LambdaQueryWrapper<Cart>().eq(Cart::getId, Long.valueOf(s)));
        }
        return Result.success();
    }

    /**
     * 根据用户名查询用户id
     * @return
     */
    private User getUserIdByUsername() {
        String username = SecurityContext.getUsername();
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<User>()
                .select(User::getId)
                .eq(User::getUsername, username);
        User user = userMapper.selectOne(queryWrapper);
        System.out.println("user" + user);
        return user;
    }
}
